"""
内存存储管理模块

MVP版本使用内存存储来管理心理评估数据
"""
import threading
from datetime import datetime, timedelta
from typing import Dict, Optional, List
from django.conf import settings
from .models import AssessmentData, AssessmentResult


class MemoryStorage:
    """内存存储管理类"""
    
    _instance = None
    _lock = threading.Lock()
    
    def __new__(cls):
        """单例模式"""
        if cls._instance is None:
            with cls._lock:
                if cls._instance is None:
                    cls._instance = super().__new__(cls)
                    cls._instance._initialized = False
        return cls._instance
    
    def __init__(self):
        """初始化存储"""
        if not self._initialized:
            self.assessment_data: Dict[str, AssessmentData] = {}
            self.assessment_results: Dict[str, AssessmentResult] = {}
            self.storage_lock = threading.RLock()
            self.max_items = getattr(settings, 'ASSESSMENT_STORAGE', {}).get('max_storage_items', 10000)
            self.cleanup_interval = getattr(settings, 'ASSESSMENT_STORAGE', {}).get('cleanup_interval', 3600)
            self.last_cleanup = datetime.now()
            self._initialized = True
    
    def store_assessment_data(self, assessment_data: AssessmentData) -> bool:
        """
        存储评估数据
        
        Args:
            assessment_data: 评估数据对象
            
        Returns:
            bool: 存储是否成功
        """
        try:
            with self.storage_lock:
                # 检查存储空间
                self._check_storage_limit()
                
                # 存储数据
                self.assessment_data[assessment_data.test_id] = assessment_data
                
                return True
        except Exception as e:
            print(f"存储评估数据失败: {e}")
            return False
    
    def get_assessment_data(self, test_id: str) -> Optional[AssessmentData]:
        """
        获取评估数据
        
        Args:
            test_id: 测试ID
            
        Returns:
            AssessmentData或None
        """
        with self.storage_lock:
            return self.assessment_data.get(test_id)
    
    def store_assessment_result(self, assessment_result: AssessmentResult) -> bool:
        """
        存储评估结果
        
        Args:
            assessment_result: 评估结果对象
            
        Returns:
            bool: 存储是否成功
        """
        try:
            with self.storage_lock:
                # 检查存储空间
                self._check_storage_limit()
                
                # 存储结果
                self.assessment_results[assessment_result.test_id] = assessment_result
                
                return True
        except Exception as e:
            print(f"存储评估结果失败: {e}")
            return False
    
    def get_assessment_result(self, test_id: str) -> Optional[AssessmentResult]:
        """
        获取评估结果
        
        Args:
            test_id: 测试ID
            
        Returns:
            AssessmentResult或None
        """
        with self.storage_lock:
            return self.assessment_results.get(test_id)
    
    def delete_assessment(self, test_id: str) -> bool:
        """
        删除评估数据和结果
        
        Args:
            test_id: 测试ID
            
        Returns:
            bool: 删除是否成功
        """
        try:
            with self.storage_lock:
                # 删除评估数据
                if test_id in self.assessment_data:
                    del self.assessment_data[test_id]
                
                # 删除评估结果
                if test_id in self.assessment_results:
                    del self.assessment_results[test_id]
                
                return True
        except Exception as e:
            print(f"删除评估数据失败: {e}")
            return False
    
    def list_recent_assessments(self, limit: int = 100) -> List[str]:
        """
        获取最近的评估ID列表
        
        Args:
            limit: 返回的最大数量
            
        Returns:
            测试ID列表
        """
        with self.storage_lock:
            # 按时间戳排序
            sorted_items = sorted(
                self.assessment_data.items(),
                key=lambda x: x[1].timestamp,
                reverse=True
            )
            return [item[0] for item in sorted_items[:limit]]
    
    def get_storage_stats(self) -> Dict[str, int]:
        """
        获取存储统计信息
        
        Returns:
            存储统计字典
        """
        with self.storage_lock:
            return {
                'total_assessments': len(self.assessment_data),
                'total_results': len(self.assessment_results),
                'max_items': self.max_items,
                'storage_usage_percent': int((len(self.assessment_data) / self.max_items) * 100)
            }
    
    def _check_storage_limit(self):
        """检查并清理存储空间"""
        current_time = datetime.now()
        
        # 定期清理
        if (current_time - self.last_cleanup).seconds > self.cleanup_interval:
            self._cleanup_old_data()
            self.last_cleanup = current_time
        
        # 如果接近存储限制，强制清理
        if len(self.assessment_data) >= self.max_items * 0.9:
            self._cleanup_old_data(force=True)
    
    def _cleanup_old_data(self, force: bool = False):
        """清理旧数据"""
        try:
            current_time = datetime.now()
            
            # 设置清理时间阈值
            if force:
                # 强制清理：删除超过1小时的数据
                threshold = current_time - timedelta(hours=1)
            else:
                # 常规清理：删除超过24小时的数据
                threshold = current_time - timedelta(hours=24)
            
            # 找出需要清理的测试ID
            ids_to_remove = []
            for test_id, data in self.assessment_data.items():
                if data.timestamp < threshold:
                    ids_to_remove.append(test_id)
            
            # 删除旧数据
            for test_id in ids_to_remove:
                self.delete_assessment(test_id)
            
            if ids_to_remove:
                print(f"清理了 {len(ids_to_remove)} 条旧数据")
        
        except Exception as e:
            print(f"清理数据时出错: {e}")
    
    def clear_all_data(self):
        """清空所有数据（仅用于测试）"""
        with self.storage_lock:
            self.assessment_data.clear()
            self.assessment_results.clear()


# 全局存储实例
storage = MemoryStorage() 